package info.pandd.centrumDowodzeniaSMS;

import info.pandd.centrumDowodzeniaSMS.SMSHistoryProviderMetaData.*;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class SMSHistoryProvider extends ContentProvider{
	//Tag do logowania
	private static final String TAG = "SMSHistoryProvider";
	public SQLiteDatabase db;
	
	//mapa projekcji kolumn
	private static HashMap<String, String> sHistoriaProjectionMap;
	
	static{
		sHistoriaProjectionMap = new HashMap<String, String>();
		sHistoriaProjectionMap.put(SMSTableMetaData._ID, SMSTableMetaData._ID);
		
		//kolumny: odbiorca - nazwa, odbiorca - numer, tresc_wiadomosci, data
		sHistoriaProjectionMap.put(SMSTableMetaData.MSG_RECEIVER_NAME, SMSTableMetaData.MSG_RECEIVER_NAME);
		sHistoriaProjectionMap.put(SMSTableMetaData.MSG_RECEIVER_NUMBER, SMSTableMetaData.MSG_RECEIVER_NUMBER);
		sHistoriaProjectionMap.put(SMSTableMetaData.MSG_TEXT, SMSTableMetaData.MSG_TEXT);
		sHistoriaProjectionMap.put(SMSTableMetaData.MSG_DATE, SMSTableMetaData.MSG_DATE);
	}
	
	//identyfikowanie wzorców przychodzących URI
	private static final UriMatcher sUriMatcher;
	private static final int INCOMING_ENTRIES_COLLECTION_URI_INDICATOR = 1;
	private static final int INCOMING_SINGLE_ENTRY_URI_INDICATOR = 2;
	
	static{
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(SMSHistoryProviderMetaData.AUTHORITY, "wyslane_wiadomosci", INCOMING_ENTRIES_COLLECTION_URI_INDICATOR);
		sUriMatcher.addURI(SMSHistoryProviderMetaData.AUTHORITY, "wyslane_wiadomosci/#", INCOMING_SINGLE_ENTRY_URI_INDICATOR);
	}
	
	//zwrotne wywołanie metody onCreate
	private DatabaseHelper mOpenHelper;
	
	@Override
	public boolean onCreate(){
		mOpenHelper = new DatabaseHelper(getContext());
		db = mOpenHelper.getWritableDatabase();
		return true;
	}
	
	private static class DatabaseHelper extends SQLiteOpenHelper{
		DatabaseHelper(Context context){
			super(context, SMSHistoryProviderMetaData.DATABASE_NAME, null, SMSHistoryProviderMetaData.DATABASE_VERSION);
		}
		
		//tworzy bazę danych
		@Override
		public void onCreate(SQLiteDatabase db){
			db.execSQL("CREATE TABLE " + SMSTableMetaData.TABLE_NAME + " ("
					+ "_id INTEGER PRIMARY KEY,"
					+ SMSTableMetaData.MSG_RECEIVER_NAME + " TEXT,"
					+ SMSTableMetaData.MSG_RECEIVER_NUMBER + " TEXT,"
					+ SMSTableMetaData.MSG_TEXT + " TEXT,"
					+ SMSTableMetaData.MSG_DATE + " TEXT"
					+");");
		}
		
		//kwestia zmiany wersji - wyczyść bazę i stwórz nową tabelę
		
		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
			Log.w(TAG, "Aktualizacja bazy danych z wersji " + oldVersion + " do wersji " + newVersion + ", w wyniku której wszystkie stare dane zostaną utracone");
			db.execSQL("DROP TABLE IF EXISTS " + SMSTableMetaData.TABLE_NAME);
			onCreate(db);
		}
	}
	
	//wszyskie metody interfejsu
	
	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		//Uwaga! czyści bazę danych
		//w przyszłości może będzie usuwać pojedyncze elementy
		db = mOpenHelper.getWritableDatabase();
		int rowId = db.delete(SMSTableMetaData.TABLE_NAME, null, null);
		return rowId;
	}

	@Override
	public String getType(Uri uri) {
		switch(sUriMatcher.match(uri)){
		case INCOMING_ENTRIES_COLLECTION_URI_INDICATOR:
			return SMSTableMetaData.CONTENT_TYPE;
		case INCOMING_SINGLE_ENTRY_URI_INDICATOR:
			return SMSTableMetaData.CONTENT_ITEM_TYPE;
		default:
			throw new IllegalArgumentException("Nieznany identyfikator URI: " + uri);
		}
	}//eof getType()

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		//sprawdzenie identyfikatora URI
		if(sUriMatcher.match(uri) != INCOMING_ENTRIES_COLLECTION_URI_INDICATOR){
			throw new IllegalArgumentException("Nieznany identyfikator URI: " + uri);
		}
		
		Long dataCzas = Long.valueOf(System.currentTimeMillis());
		
		//sprawdzenie danych wejściowych
		if(values.containsKey(SMSTableMetaData.MSG_RECEIVER_NAME) == false){
			throw new SQLException("Nie został określony odbiorca!");
		}
		if(values.containsKey(SMSTableMetaData.MSG_RECEIVER_NUMBER) == false){
			throw new SQLException("Nie został określony odbiorca!");
		}
		if(values.containsKey(SMSTableMetaData.MSG_TEXT) == false){
			throw new SQLException("Nie została określona treść wiadomości!");
		}
		if(values.containsKey(SMSTableMetaData.MSG_DATE) == false){
			values.put(SMSTableMetaData.MSG_DATE, dataCzas);
		}
		
		//dane sprawdzone, teraz czas je umieścić w bazie danych
		db = mOpenHelper.getWritableDatabase();
		long rowId = db.insert(SMSTableMetaData.TABLE_NAME, SMSTableMetaData.MSG_RECEIVER_NAME, values);
		if(rowId > 0){
			Uri insertedEntryUri = ContentUris.withAppendedId(SMSTableMetaData.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(insertedEntryUri, null);
			return insertedEntryUri;
		}
		throw new SQLException("Nieudana próba dodania wpisu do bazy danych");
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		
		switch(sUriMatcher.match(uri))
		{
		case INCOMING_ENTRIES_COLLECTION_URI_INDICATOR:
			qb.setTables(SMSTableMetaData.TABLE_NAME);
			qb.setProjectionMap(sHistoriaProjectionMap);
			break;
		case INCOMING_SINGLE_ENTRY_URI_INDICATOR:
			qb.setTables(SMSTableMetaData.TABLE_NAME);
			qb.setProjectionMap(sHistoriaProjectionMap);
			qb.appendWhere(SMSTableMetaData._ID + "=" + uri.getPathSegments().get(1));
			break;
		default:
			throw new IllegalArgumentException("Nieznany identyfikator URI: " + uri);
		}
		
		//kwestia sortowania
		String orderBy;
		if(TextUtils.isEmpty(sortOrder)){
			orderBy = SMSTableMetaData.DEFAULT_SORT_ORDER;
		}
		else{
			orderBy = sortOrder;
		}
		
		//otwieramy bazę i uruchamiamy kwerendę
		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
		
		//ustawienie obserwowania URI w przypadku zmiany źródła danych
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}//eof query()

	@Override
	public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
		//metoda niepotrzebna w projekcie, wymagana do interfejsu
		return 0;
	}
	
}